#include "SdkSpk.h"
#include "SdkMediaCommon.h"
#include "InSdkSpkCtrl.h"

#if CMAKE_SUPPORT_AAC_DECODE
#include "SdkAacDec.h"

#define DEF_AAC_DECODE_BIT_RATE        16

HANDLE_AACDECODER g_SdkSpk_AacDecHandle;
CStreamInfo *g_SdkSpk_AacDec_Info = NULL;
int g_SdkSpk_AacDec_Size = 0;
#endif

#define DEF_TAG             "Spk"

static Com_s32 g_SdkSpk_Handle = DEF_COM_FAILED;

Com_s32 g_SdkSpk_Default_Volume = 3;
Com_s32 g_SdkSpk_Default_Gain = 3;

void SdkSpk_Set_VolumeOrGain(Com_u8 v_sta,Com_s32 v_val,Com_u8 g_sta,Com_s32 g_val)
{
    if(v_sta == DEF_COM_ENABLE)
    {
        if (ak_ao_set_volume(g_SdkSpk_Handle, v_val))
        {
            ak_print_error_ex(MODULE_ID_APP, "ak_ao_set_volume failed\n");
        }
    }

    if(g_sta == DEF_COM_ENABLE)
    {
        if (ak_ao_set_gain(g_SdkSpk_Handle, g_val))
        {
            ak_print_error_ex(MODULE_ID_APP, "ak_ai_set_gain failed\n");
            return;
        }
    }
}

void SdkSpk_Reset_VolumeAndGain(void)
{
    if (ak_ao_set_volume(g_SdkSpk_Handle, g_SdkSpk_Default_Volume))
    {
        ak_print_error_ex(MODULE_ID_APP, "ak_ao_set_volume failed\n");
    }

    if (ak_ao_set_gain(g_SdkSpk_Handle, g_SdkSpk_Default_Gain))
    {
        ak_print_error_ex(MODULE_ID_APP, "ak_ai_set_gain failed\n");
        return;
    }
}

int Ext_SdkSpk_Init(void)
{
    int gain = g_SdkSpk_Default_Gain;
    int volume = g_SdkSpk_Default_Volume;

    struct ak_audio_out_param ao_param;
    struct ak_audio_nr_attr default_ao_nr_attr = {0, 0, 0};
    struct ak_audio_aslc_attr default_ao_aslc_attr = {32768,volume, 0};
    struct ak_audio_eq_attr default_ao_eq_attr = {0,10,
    {50, 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{717, 717, 717, 717, 717, 717, 717, 717, 717, 717},
    {TYPE_HPF, TYPE_PF1, TYPE_PF1, TYPE_PF1,TYPE_PF1, TYPE_PF1, TYPE_PF1, TYPE_PF1, TYPE_PF1, TYPE_PF1},
    0,0,0,0,0,0,0,{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};

    ao_param.pcm_data_attr.sample_bits = AK_AUDIO_SMPLE_BIT_16;
    ao_param.pcm_data_attr.channel_num = AUDIO_CHANNEL_MONO;
    ao_param.pcm_data_attr.sample_rate = AK_AUDIO_SAMPLE_RATE_8000;
    ao_param.dev_id = DEV_DAC;

    /* open ao */
    if (ak_ao_open(&ao_param, &g_SdkSpk_Handle))
    {
        ak_print_error_ex(MODULE_ID_APP, "ak_ao_open failed\n");
        return AK_FAILED;
    }

    if (ak_ao_set_nr_attr(g_SdkSpk_Handle, &default_ao_nr_attr))
    {
        ak_print_error_ex(MODULE_ID_APP, "ak_ao_set_nr_attr failed\n");
        return AK_FAILED;
    }

    if (ak_ao_set_aslc_attr(g_SdkSpk_Handle, &default_ao_aslc_attr))
    {
        ak_print_error_ex(MODULE_ID_APP, "ak_ao_set_aslc_attr failed\n");
        return AK_FAILED;
    }

    if (ak_ao_set_eq_attr(g_SdkSpk_Handle, &default_ao_eq_attr))
    {
        ak_print_error_ex(MODULE_ID_APP, "ak_ao_set_eq_attr failed\n");
        return AK_FAILED;
    }

    if (ak_ao_set_gain(g_SdkSpk_Handle, gain))
    {
        ak_print_error_ex(MODULE_ID_APP, "ak_ao_set_gain failed\n");
        return AK_FAILED;
    }

    if (ak_ao_set_volume(g_SdkSpk_Handle, volume))
    {
        ak_print_error_ex(MODULE_ID_APP, "ak_ao_set_volume failed\n");
        return AK_FAILED;
    }

    Ext_SdkMediaCom_SetSpk_CB_Register(SdkSpk_Set_VolumeOrGain);
    Ext_SdkMediaCom_ResetSpk_CB_Register(SdkSpk_Reset_VolumeAndGain);

    return AK_SUCCESS;
}

int Ext_SdkSpk_Exit(void)
{
    /* close ao */
    if (-1 != g_SdkSpk_Handle)
    {
        ak_ao_close(g_SdkSpk_Handle);
        g_SdkSpk_Handle = -1;
    }

    return 0;
}

void Ext_SdkMediaCom_Set_Spk_Volume(Com_s32 volume)
{
    if (ak_ao_set_volume(g_SdkSpk_Handle, volume))
    {
        ak_print_error_ex(MODULE_ID_APP, "ak_ao_set_volume failed\n");
    }
}

void Ext_SdkMediaCom_Set_Spk_Gain(Com_s32 gain)
{
    ak_ao_set_gain(g_SdkSpk_Handle,gain);
}

Com_void Ext_SdkSpk_Play(Com_pu8 buf,Com_u32 size)
{
    Com_s32 send_len = 0;

    Ext_InSdkSpkCtrl_Using();

    /* send frame and play */
    if (ak_ao_send_frame(g_SdkSpk_Handle,buf,size, &send_len))
    {
        PRT_ERR(DEF_TAG,"write pcm to DA error!\n");
        return;
    }
}

Com_s32 Ext_SdkSpk_Send_Buff(Com_u8 *buf,Com_u32 size)
{
    Com_s32 ret = -1;
    Com_s32 send_len = 0;

    Ext_InSdkSpkCtrl_Using();
    /* send frame and play */
    ret = ak_ao_send_frame(g_SdkSpk_Handle,buf,size,&send_len);
    if (ret < 0)
    {
        PRT_ERR(DEF_TAG,"write pcm to DA error!\n");
        return -1;
    }

    return 0;
}

Com_void Ext_SdkSpk_Send_End_Buff(Com_void)
{
    Com_s32 i;
    Com_s32 ret = -1;
    Com_s32 send_len = 0;
    Com_u8 buf[640];

    for(i = 0;i < 3;i++)
    {
        memset(buf,0,sizeof(buf));

        /* send frame and play */
        ret = ak_ao_send_frame(g_SdkSpk_Handle,buf,640,&send_len);
        if (ret < 0)
        {
            PRT_ERR(DEF_TAG,"write pcm to DA error!\n");
            return;
        }
        usleep(10 * 1000);
    }
}

#if CMAKE_SUPPORT_AAC_DECODE
Com_s32 Ext_SdkSpk_AacDecode_Init(void)
{
    g_SdkSpk_AacDecHandle = aacDecoder_Open(TT_MP4_ADTS, 1);
    if (!g_SdkSpk_AacDecHandle)
    {
        PRT_ERR(DEF_TAG,"aacDecoder open error\n");
        return -1;
    }

    return 0;
}

Com_void Ext_SdkSpk_AacDecode_End(void)
{
}

Com_void Ext_SdkSpk_AacDestroy_Adec(void)
{
    if (g_SdkSpk_AacDecHandle)
    {
        aacDecoder_Close(g_SdkSpk_AacDecHandle);
    }
    g_SdkSpk_AacDecHandle = NULL;
}

Com_s32 Ext_SdkSpk_AacDecode_SendBuf(char *data, int data_len)
{
    Com_u32 unb_data = data_len;
    Com_u32 unb_left = data_len;
    UCHAR *input_buf[1] = {(UCHAR *)data};
    Com_s8 buf[DEF_SDK_AAC_DEC_BUF_SIZE];
    Com_s32 len;
    AAC_DECODER_ERROR err;

    memset(buf,0,sizeof(buf));
    err = aacDecoder_Fill(g_SdkSpk_AacDecHandle,input_buf,&unb_data, &unb_left);
    if (err != AAC_DEC_OK)
    {
        PRT_ERR(DEF_TAG,"aacDecoder Fill error 0x%x\n",err);
        return -1;
    }

    err = aacDecoder_DecodeFrame(g_SdkSpk_AacDecHandle,(INT_PCM *)buf,
                                 DEF_SDK_AAC_DEC_BUF_SIZE / sizeof(INT_PCM), 0);
    if (err == AAC_DEC_NOT_ENOUGH_BITS)
    {
        PRT_ERR(DEF_TAG,"DecodeFrame error 0x%x\n",err);
        return 0;
    }

    if (err != AAC_DEC_OK)
    {
        PRT_ERR(DEF_TAG,"aacDecoder DecodeFrame 0x%x\n",err);
        return -1;
    }

    static UCHAR flag = 0;
    if(flag == 0)
    {
        g_SdkSpk_AacDec_Info = aacDecoder_GetStreamInfo(g_SdkSpk_AacDecHandle);
        g_SdkSpk_AacDec_Size = g_SdkSpk_AacDec_Info->numChannels
                * g_SdkSpk_AacDec_Info->frameSize * DEF_AAC_DECODE_BIT_RATE / 8;
        flag = 1;
    }

    len = g_SdkSpk_AacDec_Size;
    Ext_SdkSpk_Play((Com_pu8)buf,len);

    return 0;
}
#endif
